select 是類 UNIX 系統提供的一個多路復用系統 API,Golang 借用多路復用的概念,提供 select 關鍵字用於監聽多個通道
select 使用方式類似於 switch 語句,每個 case 會對應一個通道通信(接收或發送)過程,直到某個 case 的通信完成時,就會執行 case 分支對應語句
如果多個 case 同時滿足,select 會隨機選擇一個,對於沒有的 case 的 select 會一直等待
package main
import "fmt"
func main() {
ch := make(chan int, 10)
for i := 0; i < 10; i++ {
select {
case x := <-ch:
fmt.Printf("chan 接收到 %d\n", x)
case ch <- i:
fmt.Printf("發送到chan %d\n", i)
}
}
}
package main
import (
"fmt"
"sync"
"time"
)
func main() {
ch := make(chan int, 10)
ch2 := make(chan int, 10)
c := make(chan struct{}, 1)
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
ch <- i
time.Sleep(1 * time.Second)
}
close(ch)
}()
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
ch2 <- i
time.Sleep(1 * time.Second)
}
close(ch2)
}()
go func() {
Close:
for {
select {
case x, ok := <-ch:
if ok {
fmt.Printf("chan1 接收到 %d\n", x)
}
case d, ok := <-ch2:
if ok {
fmt.Printf("chan2 接收到 %d\n", d)
}
case <-c:
goto Close
}
}
}()
wg.Wait()
c <- struct{}{}
}